<template>
  <div class="dropEl" v-loading="elLoading">
    <div class="selectBox">
      <div class="select">
        <div class="select-left">
          <ul>
            <li
              v-if="
                collect.source.selectType == 2 || collect.source.selectType == 3
              "
            >
              <span>源库：</span>
              <el-select
                v-model="data.sourceDatabase"
                placeholder="请选择源库"
                size="small"
                style="width: 70%"
              >
                <el-option
                  v-for="dict in collect.source.nodeTypeOptions"
                  :key="dict.value + Math.random()"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </li>
            <li
              v-if="
                collect.source.selectType == 1 || collect.source.selectType == 3
              "
            >
              <span>源schema：</span>
              <el-select
                v-model="data.sourceDataSchema"
                placeholder="请选择源库"
                size="small"
                style="width: 75%"
              >
                <el-option
                  v-for="dict in collect.source.selectType == 1
                    ? collect.source.nodeTypeOptions
                    : collect.source.schemaSelectData"
                  :key="dict.value + Math.random()"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </li>
          </ul>
        </div>
        <div class="select-right">
          <ul>
            <li
              v-if="
                collect.sink.selectType == 2 || collect.sink.selectType == 3
              "
            >
              <span>目标库：</span>
              <el-select
                v-model="data.sinkDatabase"
                placeholder="请选择目标库"
                size="small"
                style="width: 70%"
              >
                <el-option
                  v-for="dict in collect.sink.nodeTypeOptions"
                  :key="dict.value + Math.random()"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </li>
            <li
              v-if="
                collect.sink.selectType == 1 || collect.sink.selectType == 3
              "
            >
              <span>目标schema：</span>
              <el-select
                v-model="data.sinkDataSchema"
                placeholder="请选择目标schema"
                size="small"
                style="width: 70%"
              >
                <el-option
                  v-for="dict in collect.sink.selectType == 1
                    ? collect.sink.nodeTypeOptions
                    : collect.sink.schemaSelectData"
                  :key="dict.value + Math.random()"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <el-checkbox-group
      v-if="data.taskTypeScope"
      v-model="data.taskTypeScope"
      style="margin-top: 15px"
    >
      <el-checkbox
        v-for="dict in databaseType"
        :label="dict.value"
        :key="dict.value"
        >{{ dict.label }}</el-checkbox
      >
    </el-checkbox-group>
    <div style="text-align: right">
      <el-button
        type="primary"
        size="small"
        style="width: 80px"
        @click.prevent="handleClick"
        :disabled="data.jobType[1] != 'SYNC_DATA'"
        >查询</el-button
      >
    </div>

    <div class="collapseBox" v-if="selectList.length > 0">
      <el-collapse v-model="collapseMode" @change="handelChange" accordion>
        <el-collapse-item
          v-for="(item, index) in selectList"
          :key="index"
          :title="`选择${item.label}`"
          :name="item.value"
        >
          <div class="tableBox">
            <div class="left">
              <p>源数据库</p>
              <el-table
                :key="tableUpdataKey"
                ref="sourceMultipleTable"
                :data="collect.source.table[collapseMode]"
                style="width: 100%"
                height="200"
                @selection-change="handleSelectionChange"
              >
                <el-table-column type="selection"> </el-table-column>
                <el-table-column
                  prop="instanceName"
                  label="实例名"
                  width="auto"
                />
                <el-table-column prop="name" label="表名" width="auto" />
                <el-table-column prop="rows" label="行数" width="auto" />
              </el-table>
            </div>
            <div class="right">
              <p>目标数据库</p>

              <el-table
                :key="tableUpdataKey"
                ref="sinkMultipleTable"
                :data="collect.sink.table[collapseMode]"
                style="width: 100%"
                height="200"
              >
                <el-table-column
                  prop="instanceName"
                  label="实例名"
                  width="auto"
                />
                <el-table-column prop="name" label="表名" width="auto" />
                <el-table-column prop="rows" label="行数" width="auto" />
              </el-table>
            </div>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
  </div>
</template>
<script>
import {
  databaseListObjects,
  databaseListData,
  databaseListDatabaseAndSchema,
} from "@/api/console/datasourceInfo";

import Vue from "vue";

export default {
  dicts: ["appraise_taskmode", "synchronous_tasktypescope"],
  components: {},
  props: ["data"],
  data() {
    return {
      tableData: {},
      isSelect: false,
      selectList: [],
      collapseMode: null,
      databaseType: [],
      collect: {
        source: {
          nodeTypeOptions: [],
          sourceType: "",
          table: {},
          schemaSelectData: [],
          selectType: 0,
        },
        sink: {
          nodeTypeOptions: [],
          sinkType: "",
          table: {},
          schemaSelectData: [],
          selectType: 0,
        },
      },
      tableUpdataKey: null,
      elLoading: false,
    };
  },
  async created() {
    this.elLoading = true;
    this.gainBaseSelect();
    return false;
  },
  async mounted() {
    this.assembleDatabase();
  },
  methods: {
    async gainBaseSelect() {
      const {
        start,
        end,
        sourceDatabase,
        sinkDatabase,
        sourceId,
        sinkId,
        sourceDataSchema,
        sinkDataSchema,
      } = this.$props.data;
      let res = await this.getDicts("datasource_database_type");
      res.data.forEach((f) => {
        if (start == f.dictLabel || end == f.dictLabel) {
          this.collect[start == f.dictLabel ? "source" : "sink"].selectType =
            Number(f.dictValue);
        }
      });
      Promise.all([
        databaseListDatabaseAndSchema({
          id: sourceId,
        }),
        databaseListDatabaseAndSchema({
          id: sinkId,
        }),
      ]).then((res) => {
        if (res[0].data.code == 200) {
          this.changeLibraryData(
            res[0].data.data,
            this.collect.source.nodeTypeOptions,
            this.collect.source.schemaSelectData
          );
          if (!sourceDatabase && this.collect.source.selectType != 1) {
            Vue.set(
              this.$props.data,
              "sourceDatabase",
              res[0].data.data[0].database
            );
          }
          if (!sourceDataSchema && this.collect.source.selectType != 2) {
            if (this.collect.source.selectType == 1) {
              Vue.set(
                this.$props.data,
                "sourceDataSchema",
                res[0].data.data[0].database
              );
            } else {
              Vue.set(
                this.$props.data,
                "sourceDataSchema",
                res[0].data.data[0].schemas[0]
              );
            }
          }
        }
        if (res[1].data.code == 200) {
          this.changeLibraryData(
            res[1].data.data,
            this.collect.sink.nodeTypeOptions,
            this.collect.sink.schemaSelectData
          );
          if (!sinkDatabase && this.collect.sink.selectType != 1) {
            Vue.set(
              this.$props.data,
              "sinkDatabase",
              res[1].data.data[0].database
            );
          }
          if (!sinkDataSchema && this.collect.sink.selectType != 2) {
            if (this.collect.sink.selectType == 1) {
              Vue.set(
                this.$props.data,
                "sinkDataSchema",
                res[1].data.data[0].database
              );
            } else {
              Vue.set(
                this.$props.data,
                "sinkDataSchema",
                res[1].data.data[0].schemas[0]
              );
            }
          }
        }
        if (res[0].data.code != 200 || res[1].data.code != 200) {
          this.$message.error(
            `${res[0].data.code != 200 ? "源库" : "目标库"}:${
              res[res[0].data.code != 200 ? 0 : 1].data.msg
            }`
          );
        }
        this.elLoading = false;
      });
    },
    changeLibraryData(data, value, schemas) {
      if (!data) return;
      data.forEach((f) => {
        value.push({
          label: f.database,
          value: f.database,
        });
        if (f.schemas) {
          f.schemas.forEach((v) => {
            schemas.push({
              label: v,
              value: v,
            });
          });
        }
      });
    },
    async assembleDatabase() {
      let dbType = await this.getDicts("db_object_type");
      let taskTypescope = await this.getDicts("synchronous_tasktypescope");
      let selectData = [];
      dbType = dbType.data
        .find((f) => {
          return f.dictLabel == this.$props.data.start;
        })
        .dictValue.split(",");
      if (
        this.$props.data.jobMode == "BATCH" ||
        this.$props.data.jobMode == "STREAMING"
      ) {
        this.databaseType.push({
          label: "表",
          value: "CREATE_TABLE",
        });
        Vue.set(this.$props.data, "taskTypeScope", ["CREATE_TABLE"]);
        if (this.$props.data.jobType[1] == "SYNC_DATA") {
          this.handleClick();
        }
        return;
      }
      if (this.$props.data.jobType[0] == "basic") {
        let type = this.$props.data.jobType[1].split("_")[1];
        taskTypescope.data.forEach((j) => {
          if (j.dictValue.includes(type)) {
            this.databaseType.push({
              label: j.dictLabel,
              value: j.dictValue,
            });
          }
          return;
        });
      }
      if (this.$props.data.jobType[0] == "common") {
        dbType.forEach((f) => {
          taskTypescope.data.forEach((j) => {
            if (j.dictValue.includes(f.toUpperCase())) {
              this.databaseType.push({
                label: j.dictLabel,
                value: j.dictValue,
              });
            }
          });
        });
      }
      this.databaseType.forEach((f, i) => {
        selectData.push(f.value);
      });
      Vue.set(this.$props.data, "taskTypeScope", selectData);
    },
    handelChange(v) {
      if (v.length > 0 && this.$props.data.jdbc) {
        this.toggleSelection(this.$props.data.jdbc);
      }
    },
    handleClick() {
      if (!this.$props.data.sourceDatabase && !this.$props.data.sinkDatabase) {
        return;
      }
      this.elLoading = true;
      this.gainTable();
    },
    handleSelectionChange(v) {
      if (this.collapseMode == 0) return;
      this.$props.data.jdbc = [...v];
    },
    toggleSelection(rows) {
      if (rows) {
        let that = this;
        this.$nextTick(() => {
          that.collect.source.table[that.collapseMode].forEach((f) => {
            rows.forEach((row) => {
              if (f.name == (row.name || row.tableName)) {
                this.$refs.sourceMultipleTable[0].toggleRowSelection(f, true);
              }
            });
          });
        });
      } else {
        this.$refs.sourceMultipleTable.clearSelection();
      }
    },
    async gainTable() {
      let select = [];
      let mode = await this.getDicts("appraise_taskmode");
      this.selectList = [];
      if (
        this.$props.data.taskTypeScope &&
        this.$props.data.taskTypeScope.length == 0
      ) {
        this.collect.sink.table = {};
        this.collect.source.table = {};
        this.tableUpdataKey = Math.random();
        this.elLoading = false;
        return;
      }
      this.$props.data.taskTypeScope.forEach((f) => {
        let name = f.split("_")[1].toLowerCase();
        select.push(name);
        let item = mode.data.find((j) => j.dictValue == name);
        if (item) {
          this.selectList.push({
            label: item.dictLabel,
            value: item.dictValue,
          });
        }
      });
      let dataObj = {
        databaseName: this.$props.data.sourceDatabase,
        taskMode: select.join(","),
        id: this.$props.data.sourceId,
      };
      if (
        this.collect.source.selectType == 1 ||
        this.collect.source.selectType == 3
      ) {
        dataObj.databaseName = this.$props.data.sourceDataSchema;
      }
      // 源table
      const sourceTable = await databaseListObjects(dataObj);
      dataObj.id = this.$props.data.sinkId;
      if (
        this.collect.sink.selectType == 1 ||
        this.collect.sink.selectType == 3
      ) {
        dataObj.databaseName = this.$props.data.sinkDataSchema;
      }
      // 目标table
      const skinTable = await databaseListObjects(dataObj);
      select.forEach((f) => {
        this.collect.sink.table[f] = [];
        this.collect.source.table[f] = [];
        if (sourceTable.data.data) {
          sourceTable.data.data[f]?.forEach((v, i) => {
            let findItem;
            if (this.$props.data.jdbc) {
              findItem = this.$props.data.jdbc.find(
                (j) => j.tableName == v[`${f}Name`]
              );
            }
            this.collect.source.table[f].push({
              instanceName: this.$props.data.sourceDatabase,
              name: v[`${f}Name`],
              comment: v.comment,
              rows: v.rows,
            });
          });
        }
        if (skinTable.data.data) {
          skinTable.data.data[f]?.forEach((v, i) => {
            this.collect.sink.table[f].push({
              instanceName:
                this.$props.data.sinkDatabase ||
                this.$props.data.sinkDataSchema,
              name: v[`${f}Name`],
              comment: v.comment,
              rows: v.rows,
            });
          });
        }
      });
      this.tableUpdataKey = Math.random();
      this.elLoading = false;
    },
  },
};
</script>

<style lang="scss" scoped>
.dropEl {
  width: 90%;
  margin: 30px auto;
  border: 1px solid #dcdfe6;
  padding: 20px 40px 40px 40px;

  button {
    margin-left: 15px;
  }
  .tableBox {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .left,
    .right {
      width: 48%;
    }
  }

  .collapseBox {
    margin-top: 15px;
  }

  .selectBox {
    .select {
      display: flex;
      width: 100%;
      span {
        color: #555;
        font-size: 14px;
      }
      .select-left {
        width: 50%;
      }

      .select-right,
      .select-left {
        width: 50%;
        padding-right: 15px;
      }

      ul {
        margin: 0;
        list-style-type: none;
        padding: 0;
        li {
          margin-top: 20px;
          padding: 0;
          width: 100%;
          height: 100%;

          span {
            display: inline-block;
            width: 100px;
          }
        }
      }
    }
  }
}
</style>
